iT邦幫忙

2023 iThome 鐵人賽

DAY 29
0
SideProject30

Nuxt3的初心者之旅:淬鍊出屬於自己的金融投資儀表板系列 第 29

DAY29 - 重新上路 - 調整部分UI(3)

  • 分享至 

  • xImage
  •  

今日工事

調整股票單頁的公司資料
比較績效的按鈕
股票篩選頁select排版

程式碼

// [id].vue

<div class="w-[33%] flex flex-wrap">
  <div
    v-for="(value, key) in stockData"
    :key="key"
    class="w-[25%] mt-5"
  >
    <div
      class="flex items-center font-bold text-base italic min-h-[30px] stockborder"
    >
      {{ translateKey(key) }}
    </div>
    <div class="flex items-start font-normal text-xs min-h-[60px]">
      {{ value }}
    </div>
  </div>
</div>
//...略
        <ClientOnly>
          <div class="flex items-center">
            <div class="p-1 flex items-center">
              <font-awesome-icon
                :icon="['fas', 'circle-plus']"
                size="xl"
                style="color: #157d7f"
                @click="searchAdd = !searchAdd"
                
              />
              <label for="typeahead_add" @click="searchAdd = !searchAdd" class="ms-1 text-[18px] font-bold"
                >比較股票績效</label
              >
            </div>
            <vue3-simple-typeahead
              id="typeahead_add"
              placeholder="搜尋股票..."
              v-if="searchAdd"
              class="w-[300px] m-4 p-1 bg-white rounded shadow :active:border-white"
              :items="checkData"
              :minInputLength="1"
              v-model="searchAddStock"
              @onInput="onInputEventHandler"
              @keydown.native.enter="changeChart('add')"
              @selectItem="selecAddtItem"
            >
              <template #list-item-text="slot">
                <div class="">
                  <span
                    class="inline-block w-[300px] bg-white rounded shadow ms-4 mb-1"
                    v-html="slot.boldMatchText(slot.itemProjection(slot.item))"
                  ></span>
                </div>
              </template>
            </vue3-simple-typeahead>
          </div>
          <div class="flex items-center">
            <div class="p-1">
              <font-awesome-icon
                :icon="['fas', 'circle-minus']"
                size="xl"
                style="color: #157d7f"
                class="inline-block"
                @click="searchRemove = !searchRemove"
              />
              <label
                for="typeahead_remove"
                @click="searchRemove = !searchRemove"
                class="ms-1 text-[18px] font-bold"
                >刪減股票績效</label
              >
            </div>
            <vue3-simple-typeahead
              id="typeahead_remove"
              placeholder="搜尋股票..."
              v-if="searchRemove"
              class="w-[300px] m-4 p-1 bg-white rounded shadow :active:border-white"
              :items="checkData"
              :minInputLength="1"
              v-model="searchRemoveStock"
              @onInput="onInputEventHandler"
              @keydown.native.enter="changeChart('remove')"
              @selectItem="selectRemoveItem"
            >
              <template #list-item-text="slot">
                <div class="">
                  <span
                    class="inline-block w-[300px] bg-white rounded shadow ms-4 mb-1"
                    v-html="slot.boldMatchText(slot.itemProjection(slot.item))"
                  ></span>
                </div>
              </template>
            </vue3-simple-typeahead>
          </div>
        </ClientOnly>

<script setup>

// API
const stockFundamentalApi = `https://financialmodelingprep.com/api/v3/profile/${id}?apikey=${fmp}`
const stockChartApi = `https://financialmodelingprep.com/api/v3/historical-price-full/${id}?timeseries=365&apikey=${fmp}`

const getDataApi = ()=>{
  const getStockFundamental = axios.get(stockFundamentalApi)
  const getFirstChart = axios.get(stockChartApi)
 return [getFirstChart,getStockFundamental]
}

// 股票基本資料
const stockData = ref()

// 股票技術線圖
const stockChart = ref()

const getData = () => {
  Promise.all(getDataApi())
    .then((res) => {
      stockChart.value = res[0].data.historical
      stockData.value = res[1].data.map(
        ({
          exchange,
          description,
          zip,
          dcfDiff,
          dcf,
          image,
          defaultImage,
          isEtf,
          isActivelyTrading,
          isAdr,
          isFund,
          ipoDate,
          ...rest
        }) => rest
      )
      stockData.value = stockData.value[0]
    })
    .catch((rej) => {
      console.log(rej)
    })
}

onMounted(() => {
  getData()
})

</script>

// stockFilter.vue

      <div class="w-[90%] mx-auto mt-5 mb-10 py-10 flex flex-wrap shadow ">
        <div class="my-1 w-[30%] flex justify-end">
          <label for="marketCap" class="font-bold">市值超過:</label>
          <select
            class="border border-solid border-[#bebebe] rounded shadow ms-2 w-[250px]"
            id="marketCap"
            v-model="marketCapMore"
            @change="getData"
          >
            <option value="" key="none" label="請選擇" />
            <option
              v-for="(v,i) in marketCapOption"
              :value="v.value"
              :key="i"
              :label="v.label"
            />
          </select>
        </div>
        //...略
      </div>

公司資料的部分
map的參數利用解構的方式
把不要的key解構出來
只return要的資料

https://ithelp.ithome.com.tw/upload/images/20231014/201625738yHaxPfkWk.png

比較績效跟刪除績效的部分加上label提醒使用者

https://ithelp.ithome.com.tw/upload/images/20231014/201625738JntnLoSp1.png

股票篩選的部分將選項靠右對齊

https://ithelp.ithome.com.tw/upload/images/20231014/201625730WAOf88V6M.png

小結

終於啊
明天就是期盼已久的那一天了!!

最後再跟各位分享心得及需要精進的部分


上一篇
DAY28 - 重新上路 - 調整部分UI(2)
下一篇
DAY30 - 是結束也是開始 - 完賽感言
系列文
Nuxt3的初心者之旅:淬鍊出屬於自己的金融投資儀表板30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言